import { Component, OnInit } from '@angular/core';
import { NzMessageService} from 'ng-zorro-antd/message';
import { Observable, Observer } from 'rxjs';
import { HttpClient, HttpRequest } from '@angular/common/http';
import { UploadXHRArgs } from 'ng-zorro-antd/upload';
import { forkJoin } from 'rxjs';
import {Service} from '../service/service';
import {Config} from '../service/config';

@Component({
  selector: 'app-classify',
  templateUrl: './classify.component.html',
  styleUrls: ['./classify.component.scss']
})
export class ClassifyComponent implements OnInit {
  API_URL:string = '';
  constructor(private httpClient: HttpClient, private msg: NzMessageService,private service: Service) {
    this.API_URL = Config.API_URL;
    this.getAllClassify();
  }
  // 修改
  isVisible = false;
  isOkLoading = false;
  editName = '';
  // 增加
  addVisible = false;
  addOkLoading = false;
  addName = '';
  // 临时存的id，用于增加，修改，图片上传
  id:number = 0;
  listOfMapData: TreeNodeInterface[] = [];
  mapOfExpandedData: { [id: string]: TreeNodeInterface[] } = {};
  showModal(data): void {
    this.editName = data.name;
    this.id = data.id;
    this.isVisible = true;
  }

  handleOk(): void {
    this.isOkLoading = true;
    const data = {
      id: this.id,
      name: this.editName
    };
    this.service.classifyUpdate(data, (result) => {
      if(result.status == 1){
        this.msg.info("修改成功");
      }else{
        this.msg.info("修改失败");
      }
      this.getAllClassify();
      this.isVisible = false;
      this.isOkLoading = false;
    });
  }

  handleCancel(): void {
    this.isVisible = false;
  }
  // 增加
  showAddModal(data): void {
    this.id = data.id;
    this.addVisible = true;
  }
  handleAddCancel(): void {
    this.addVisible = false;
  }
  handleAddOk(): void {
    this.addOkLoading = true;
    // 判断是不是新增子级，还是第一级
    const data = {
      name: this.addName
    };
    if(this.id != 0 ){
      data['id'] = this.id;
    }

    this.service.classifyAdd(data, (result) => {
      if(result.status == 1){
        this.msg.info("添加成功");
      }else{
        this.msg.info("添加失败");
      }
      this.getAllClassify();
      this.addVisible = false;
      this.addOkLoading = false;
    });

  }

  collapse(array: TreeNodeInterface[], data: TreeNodeInterface, $event: boolean): void {
    if ($event === false) {
      if (data.childrens) {
        data.childrens.forEach(d => {
          const target = array.find(a => a.id === d.id)!;
          target.expand = false;
          this.collapse(array, target, false);
        });
      } else {
        return;
      }
    }
  }

  convertTreeToList(root: TreeNodeInterface): TreeNodeInterface[] {
    const stack: TreeNodeInterface[] = [];
    const array: TreeNodeInterface[] = [];
    const hashMap = {};
    stack.push({ ...root, expand: false });

    while (stack.length !== 0) {
      const node = stack.pop()!;
      this.visitNode(node, hashMap, array);
      if (node.childrens) {
        for (let i = node.childrens.length - 1; i >= 0; i--) {
          stack.push({ ...node.childrens[i], expand: false, parent: node });
        }
      }
    }

    return array;
  }

  visitNode(node: TreeNodeInterface, hashMap: { [id: string]: boolean }, array: TreeNodeInterface[]): void {
    if (!hashMap[node.id]) {
      hashMap[node.id] = true;
      array.push(node);
    }
  }
  getAllClassify() {
    this.service.classifyQuery(null, (result) => {
      result.data.forEach(item=>{
        item.image = Config.API_URL + item.image;
      })
      this.listOfMapData = result.data;
      this.listOfMapData.forEach(item => {
        this.mapOfExpandedData[item.id] = this.convertTreeToList(item);
      });
    });

  }
  // 分类图片上传
  loading = false;
  beforeUpload = (file: File) => {
    return new Observable((observer: Observer<boolean>) => {
      const isJPG = file.type === 'image/jpeg' || 'image/png';
      if (!isJPG) {
        this.msg.error('You can only upload JPG file!');
        observer.complete();
        return;
      }
      const isLt2M = file.size / 1024 / 1024 < 2;
      if (!isLt2M) {
        this.msg.error('Image must smaller than 2MB!');
        observer.complete();
        return;
      }
      // check height
      this.checkImageDimension(file).then(dimensionRes => {
        if (!dimensionRes) {
          this.msg.error('宽高小于800');
          observer.complete();
          return;
        }

        observer.next(isJPG && isLt2M && dimensionRes);
        observer.complete();
      });
    });
  }

  private checkImageDimension(file: File): Promise<boolean> {
    return new Promise(resolve => {
      const img = new Image(); // create image
      img.src = window.URL.createObjectURL(file);
      img.onload = () => {
        const width = img.naturalWidth;
        const height = img.naturalHeight;
        console.log(width,height)
        window.URL.revokeObjectURL(img.src!);
        resolve(width <= 800 && height <= 800);
      };
    });
  }
  uploadId(id){
    this.id = id;
  }

  // ==============
  customReq = (item: UploadXHRArgs) => {
    // Create a FormData here to store files and other parameters.
    const formData = new FormData();
    let id:any = this.id;
    formData.append('image', item.file as any);
    formData.append('id', id);
    this.service.uploadClassifyImg(formData, (result) => {
      console.log(result);
      if(result.status == 1){
        this.msg.info('图片上传成功');
        this.getAllClassify();
      }
    });
  }
  // A simple sliced upload.
  customBigReq = (item: UploadXHRArgs) => {
    const size = item.file.size;
    const chunkSize = parseInt(size / 3 + '', 10);
    const maxChunk = Math.ceil(size / chunkSize);
    const reqs = Array(maxChunk)
      .fill(0)
      .map((_: {}, index: number) => {
        const start = index * chunkSize;
        let end = start + chunkSize;
        if (size - end < 0) {
          end = size;
        }
        const formData = new FormData();
        formData.append('file', item.file.slice(start, end));
        formData.append('start', start.toString());
        formData.append('end', end.toString());
        formData.append('index', index.toString());
        const req = new HttpRequest('POST', item.action!, formData, {
          withCredentials: true
        });
        return this.httpClient.request(req);
      });
    return forkJoin(...reqs).subscribe(
      () => {
        item.onSuccess!({}, item.file!, event);
      },
      err => {
        item.onError!(err, item.file!);
      }
    );
  }
  ngOnInit(): void {

  }
}
export interface TreeNodeInterface {
  id: number;
  name: string;
  icon: string;
  expand?: boolean;
  childrens?: TreeNodeInterface[];
  parent?: TreeNodeInterface;
}
